<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>RTC服务器</title>
    <script crossorigin="anonymous" integrity="sha512-WL6WGKMPBiM9PnHRYIn5YEtq0Z8XP4fkVb4qy7PP4vhmYQErJ/dySyXuFIMDf1eEYCXCrQrMJfkNwKc9gsjTjA==" src="https://lib.baomitu.com/socket.io/4.2.0/socket.io.js"></script>
</head>

<body>
    <!-- <button onclick="addRTC()">创建新连接</button> -->
    <div id="title">RTC服务器</div>
    <div id="onlineCounts">[在线人数]：0人</div>
    <div>[玩家列表]：</div>
    <div id="playerList"></div>
    <div>[状态日志]：</div>
    <div id="serverList"></div>
    <div>[消息广播]：</div>
    <div class="message" id="messageoutput"></div>
    <script>

        let roomData={
            players:[]
        }

        let rtcs=[]

        let roomId=getQueryVariable("roomId")

        document.getElementById("title").innerHTML=`RTC服务端[房间ID:${roomId}]`
        document.title=`RTC服务端[房间ID:${roomId}]`


        function getQueryVariable(variable)
        {
            var query = window.location.search.substring(1);
            var vars = query.split("&");
            for (var i=0;i<vars.length;i++) {
                    var pair = vars[i].split("=");
                    if(pair[0] == variable){return pair[1];}
            }
            return(false);
        }

        const socket = io.connect("ws://115.28.163.25:3004");

        socket.on("connect", () => {
            console.log("socket成功")  
            socket.on('disconnected', ()=> {
                console.log("socket断开")  
            });
            setInterval(()=>{
                roomUpdate()
                updateOnlineCounts()
            },500)
        });

        // socket.on("disconnected", () => {
        //     console.log("socket断开")  
        // });

        // socket.on("error", (e) => {
        //     console.log("socket断开",e)  
        // });

        function roomUpdate(){
            socket.emit("roomUpdate", {roomId});
        }

        function updateOnlineCounts(){
            document.getElementById("onlineCounts").innerHTML=`[在线人数]：${getRTCSLength()}人`
            let playerListDom =`<div>`
            for(let id in rtcs){
                playerListDom+=`<div>${id}</div>`
            }
            playerListDom+=`</div>`
            document.getElementById("playerList").innerHTML=playerListDom        
        }

        /**
         * 获取在线人数
        */
        function getRTCSLength(){
            let i=0
            for(var n in rtcs)             
            {
                i++;                        
            }
            return i;
        }

        // handle the event sent with socket.send()
        socket.on("join"+roomId, data => {
            console.log(data);
            joinRTC(data.uid)
        });

        // handle the event sent with socket.send()
        socket.on("setAnswer"+roomId, data => {
            console.log(data,data.uid);
            console.log(rtcs[data.uid])
            rtcs[data.uid].pc.PCSsetAnswer(data.answer)
        });


        /**
         * 加入RTC服务器
        */
        
        function joinRTC(uid){
            rtcs[uid]=new createRTC(uid)
            pushServerList(`<div>玩家[${uid}]尝试加入服务器</div>`)
        }

        function broadcastRTC(data){
            console.log(rtcs)
            for(let item in rtcs){
                console.log(item)
                rtcs[item].dc.send(data);
            }
        }

        function pushServerList(val){
            let listDom=document.createElement("div")
            listDom.innerHTML=val
            document.getElementById("serverList").appendChild(listDom)
        }

        let servers = [
    "iphone-stun.strato-iphone.de:3478",
    "numb.viagenie.ca:3478",
    "stun.12connect.com:3478",
    "stun.12voip.com:3478",
    "stun.1und1.de:3478",
    "stun.3cx.com:3478",
    "stun.acrobits.cz:3478",
    "stun.actionvoip.com:3478",
    "stun.advfn.com:3478",
    "stun.altar.com.pl:3478",
    "stun.antisip.com:3478",
    "stun.avigora.fr:3478",
    "stun.bluesip.net:3478",
    "stun.cablenet-as.net:3478",
    "stun.callromania.ro:3478",
    "stun.callwithus.com:3478",
    "stun.cheapvoip.com:3478",
    "stun.cloopen.com:3478",
    "stun.commpeak.com:3478",
    "stun.cope.es:3478",
    "stun.counterpath.com:3478",
    "stun.counterpath.net:3478",
    "stun.dcalling.de:3478",
    "stun.demos.ru:3478",
    "stun.dus.net:3478",
    "stun.easycall.pl:3478",
    "stun.easyvoip.com:3478",
    "stun.ekiga.net:3478",
    "stun.epygi.com:3478",
    "stun.etoilediese.fr:3478",
    "stun.faktortel.com.au:3478",
    "stun.freecall.com:3478",
    "stun.freeswitch.org:3478",
    "stun.freevoipdeal.com:3478",
    "stun.gmx.de:3478",
    "stun.gmx.net:3478",
    "stun.halonet.pl:3478",
    "stun.hoiio.com:3478",
    "stun.hosteurope.de:3478",
    "stun.infra.net:3478",
    "stun.internetcalls.com:3478",
    "stun.intervoip.com:3478",
    "stun.ipfire.org:3478",
    "stun.ippi.fr:3478",
    "stun.ipshka.com:3478",
    "stun.it1.hr:3478",
    "stun.ivao.aero:3478",
    "stun.jumblo.com:3478",
    "stun.justvoip.com:3478",
    "stun.l.google.com:19302",
    "stun.linphone.org:3478",
    "stun.liveo.fr:3478",
    "stun.lowratevoip.com:3478",
    "stun.lundimatin.fr:3478",
    "stun.mit.de:3478",
    "stun.miwifi.com:3478",
    "stun.modulus.gr:3478",
    "stun.myvoiptraffic.com:3478",
    "stun.netappel.com:3478",
    "stun.netgsm.com.tr:3478",
    "stun.nfon.net:3478",
    "stun.nonoh.net:3478",
    "stun.nottingham.ac.uk:3478",
    "stun.ooma.com:3478",
    "stun.ozekiphone.com:3478",
    "stun.pjsip.org:3478",
    "stun.poivy.com:3478",
    "stun.powervoip.com:3478",
    "stun.ppdi.com:3478",
    "stun.qq.com:3478",
    "stun.rackco.com:3478",
    "stun.rockenstein.de:3478",
    "stun.rolmail.net:3478",
    "stun.rynga.com:3478",
    "stun.schlund.de:3478",
    "stun.sigmavoip.com:3478",
    "stun.sip.us:3478",
    "stun.sipdiscount.com:3478",
    "stun.sipgate.net:10000",
    "stun.sipgate.net:3478",
    "stun.siplogin.de:3478",
    "stun.sipnet.net:3478",
    "stun.sipnet.ru:3478",
    "stun.sippeer.dk:3478",
    "stun.siptraffic.com:3478",
    "stun.sma.de:3478",
    "stun.smartvoip.com:3478",
    "stun.smsdiscount.com:3478",
    "stun.solcon.nl:3478",
    "stun.solnet.ch:3478",
    "stun.sonetel.com:3478",
    "stun.sonetel.net:3478",
    "stun.sovtest.ru:3478",
    "stun.srce.hr:3478",
    "stun.stunprotocol.org:3478",
    "stun.t-online.de:3478",
    "stun.tel.lu:3478",
    "stun.telbo.com:3478",
    "stun.tng.de:3478",
    "stun.twt.it:3478",
    "stun.uls.co.za:3478",
    "stun.unseen.is:3478",
    "stun.usfamily.net:3478",
    "stun.viva.gr:3478",
    "stun.vivox.com:3478",
    "stun.vo.lu:3478",
    "stun.voicetrading.com:3478",
    "stun.voip.aebc.com:3478",
    "stun.voip.blackberry.com:3478",
    "stun.voip.eutelia.it:3478",
    "stun.voipblast.com:3478",
    "stun.voipbuster.com:3478",
    "stun.voipbusterpro.com:3478",
    "stun.voipcheap.co.uk:3478",
    "stun.voipcheap.com:3478",
    "stun.voipgain.com:3478",
    "stun.voipgate.com:3478",
    "stun.voipinfocenter.com:3478",
    "stun.voipplanet.nl:3478",
    "stun.voippro.com:3478",
    "stun.voipraider.com:3478",
    "stun.voipstunt.com:3478",
    "stun.voipwise.com:3478",
    "stun.voipzoom.com:3478",
    "stun.voys.nl:3478",
    "stun.voztele.com:3478",
    "stun.webcalldirect.com:3478",
    "stun.wifirst.net:3478",
    "stun.xtratelecom.es:3478",
    "stun.zadarma.com:3478",
    "stun1.faktortel.com.au:3478",
    "stun1.l.google.com:19302",
    "stun2.l.google.com:19302",
    "stun3.l.google.com:19302",
    "stun4.l.google.com:19302",
    "stun.nextcloud.com:443",
    "relay.webwormhole.io:3478"
];

let configuration= {"iceServers":[{"urls":["stun:stun.epygi.com:3478"]}],"iceTransportPolicy":"all","iceCandidatePoolSize":"0"}

        
        // for (let item of servers){
        //     configuration.iceServers.push(
        //         { urls: `stun:${item}` }
        //     )
        // }

        function createRTC(uid) {

            // 创建WebRTC对象
            this.pc = new RTCPeerConnection(configuration);
            console.log(this.pc)

            // 创建WebRTC数据通道，可以传输自定义数据
            this.dc = this.pc.createDataChannel("channel");

            // 数据通道开启
            this.dc.onopen = () => console.log("Data Channel Opened");

            // 数据通道收到数据的事件
            this.dc.onmessage = (e) => {
                console.log("Get Message：", e.data)
                this.updateMessageBox(`${uid}号:${e.data}`)
                broadcastRTC(`${uid}号:${e.data}`)
            };

            this.updateMessageBox=(data) => {
                let node = document.createElement("div");
                node.innerHTML = data
                document.getElementById("messageoutput").appendChild(node)
            }

            // SDP变化的事件
            this.pc.onicegatheringstatechange = (e) => {
                if (this.pc.iceGatheringState === "complete") {  // 在SPD创建完成的时候打印他
                    console.log(JSON.stringify(this.pc.localDescription));
                    pushServerList(`<div>玩家[${uid}]加入服务器成功</div>`)
                    socket.emit("setOffer", {uid,offer:JSON.stringify(this.pc.localDescription)});
                }
                console.log(e)
            }

            this.pc.onconnectionstatechange = (e) => {
                switch(this.pc.connectionState) {
                    case "connected":
                    // The connection has become fully connected
                    console.log(`${uid}号 connected`)
                    break;
                    case "disconnected":
                    console.log(`${uid}号 disconnected`)
                    pushServerList(`<div>玩家[${uid}]退出服务器</div>`)
                    delete rtcs[uid];
                    case "failed":
                    // One or more transports has terminated unexpectedly or in an error
                    console.log(`${uid}号 failed`)
                    pushServerList(`<div>玩家[${uid}]链接失败</div>`)
                    delete rtcs[uid];
                    break;
                    case "closed":
                    // The connection has been closed
                    console.log(`${uid}号 closed`)
                    pushServerList(`<div>玩家[${uid}]关闭链接</div>`)
                    delete rtcs[uid];
                    break;
                }

                
            }

            /**
            * 创建Offer
            * @return {Promise<void>}
            */
            this.pc.PCScreateOffer=async ()=> {
                let offer = await this.pc.createOffer();
                console.log(offer)
                await this.pc.setLocalDescription(offer);
            }

            this.pc.PCSsetAnswer=async (Answer)=> {
               // var Answer = document.getElementById(`text_${uid}`).value;
                await this.pc.setRemoteDescription(JSON.parse(Answer));
                console.log("Answer Set");
            }

            this.pc.PCScreateOffer()
        }



    </script>
</body>

</html>